/** 日期 */
const WEEK_NAME_MAP = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"];

/** 渲染日期 */
export const RENDER_WEEK_NAME_MAP = [
  "周一",
  "周二",
  "周三",
  "周四",
  "周五",
  "周六",
  "周日",
];

/** 日期格式 */
export type DayType = {
  /** 当前是几号 */
  day: number;
  /**  星期 */
  weekName?: string;
  /** 是否今天 是-true */
  isToday: boolean;
};

/** calendar 数据格式 */
type DataType = {
  /** 年份 */
  year: number;
  /** 月份 */
  month: number;
  /** 天 */
  day?: number;
};

class calendar {
  #data: DataType = {
    year: 0,
    month: 0,
    day: 0,
  };

  /** 计算后的日期 */
  #dayList: Array<DayType> = [];

  /** 给时间属性添加特殊处理，添加参数。。。。。。 */
  #businessFn: (list: Array<DayType>, data: DataType) => Array<DayType>;

  /** 构造函数 */
  constructor(
    businessFn: (list: Array<DayType>, data: DataType) => Array<DayType>,
    year: number,
    month: number
  ) {
    this.#businessFn = businessFn;
    this.#data.year = year;
    this.#data.month = month;
    this.#handleDateChange({ year, month });
  }

  /** 内部函数-计算当前日期 */
  #calcDayList() {
    const { year, month } = this.#data;

    const totalDay = this.#getThisMonthDays(year, month);
    const firstDay = this.#getFirstDayOfWeek(year, month);

    const dayList: Array<DayType> = [];

    // 初始化数据
    for (let i = 0; i < totalDay; i++) {
      dayList.push({
        day: i + 1,
        weekName: WEEK_NAME_MAP[(firstDay + i) % 7],
        isToday: false,
      });
    }

    // 向前添加
    for (let i = 0; i < (firstDay || 7) - 1; i++) {
      dayList.unshift({ day: 0, isToday: false });
    }

    // 向后添加
    for (let i = 0; i < 42 - totalDay - ((firstDay || 7) - 1); i++) {
      dayList.push({ day: 0, isToday: false });
    }

    // 当天
    const now = new Date();
    if (now.getFullYear() === year && now.getMonth() + 1 === month) {
      // 寻找今天
      const currentDay = dayList.find((d) => d.day === now.getDate());
      if (currentDay) {
        currentDay.isToday = true;
      }
    }
    // 赋值
    this.#dayList = this.#businessFn(dayList, this.#data);
  }

  /** 内部函数-处理日期变化 */
  #handleDateChange(time: DataType) {
    const date = { ...this.#data, ...time };
    if (date) {
      // 当date 有值时, 保存当前值
      this.#data = date;
      // 如果年份、月份变化，重新计算日期列表
      if (time.year || time.month) this.#calcDayList();
    }
  }

  /** 内部函数-获取当月共多少天 */
  #getThisMonthDays(year: number, month: number) {
    return new Date(year, month, 0).getDate();
  }

  /** 内部函数-获取当月第一天星期几   0 星期日 */
  #getFirstDayOfWeek(year: number, month: number) {
    return new Date(Date.UTC(year, month - 1, 1)).getDay();
  }

  /** 点击上个月 */
  handlePrevMonthClick() {
    console.log("点击了上个月", this);
    let year = this.#data.year;
    let month = this.#data.month;
    if (this.#data.month === 1) {
      year = this.#data.year - 1;
      month = 12;
    } else {
      month = this.#data.month - 1;
    }
    this.#handleDateChange({ year, month });
  }

  /** 点击下个月 */
  handleNextMonthClick() {
    console.log("点击了下个月");
    let year = this.#data.year;
    let month = this.#data.month;
    if (this.#data.month === 12) {
      year = this.#data.year + 1;
      month = 1;
    } else {
      month = this.#data.month + 1;
    }
    this.#handleDateChange({ year, month });
  }

  /** 指定月份查询 */
  appointYearOrMonth(year: number, month: number) {
    this.#handleDateChange({ year, month });
  }
}

export default calendar;
